package com.ete.lib.upload.net.http

import com.blankj.utilcode.util.LogUtils
import com.ete.lib.upload.UploadConstant
import com.ete.lib.upload.net.http.ssl.SSLSocketClient
import com.ete.lib.upload.net.logging.Level
import com.ete.lib.upload.net.logging.LoggingInterceptor
import com.ete.lib.upload.net.logging.RequestHeaderInterceptor
import com.ete.lib.upload.net.progress.IProgressListener
import com.ete.lib.upload.net.progress.ProgressInterceptor
import okhttp3.ConnectionPool
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import okhttp3.internal.platform.Platform
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * Author:LiXian
 * <p>
 * Desc:网络请求创建
 * Version:1.0
 * date 2023/2/16 9:35
 */
object RetrofitClient {

    private var baseUrl = UploadConstant.DEFAULT_BASE_URL
    private var mBuilder: Retrofit.Builder? = null

    private val mLoggingInterceptor: LoggingInterceptor = LoggingInterceptor.Builder() //构建者模式
        .loggable(true) //是否开启日志打印
        .setLevel(Level.BODY) //打印的等级
        .log(Platform.INFO) // 打印类型
        .request("Request") // request的Tag
        .response("Response") // Response的Tag
        .build()

    private val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(mLoggingInterceptor)
        .connectTimeout(UploadConstant.TIME_FIFTEEN_SECOND, TimeUnit.SECONDS)
        .readTimeout(UploadConstant.TIME_FIFTEEN_SECOND, TimeUnit.SECONDS)
        .writeTimeout(UploadConstant.TIME_FIFTEEN_SECOND, TimeUnit.SECONDS)
        .retryOnConnectionFailure(false) // 需要设置为false, 否则超时时间回变成设置的2倍
        .connectionPool(ConnectionPool())
        .addInterceptor(RequestHeaderInterceptor())
        .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
        .hostnameVerifier(SSLSocketClient.getHostnameVerifier())

    private fun getRetrofitBuilder(): Retrofit.Builder {
        if (mBuilder == null) {
            synchronized(RetrofitClient::class.java) {
                if (mBuilder == null) {
                    mBuilder = Retrofit.Builder()
                        .baseUrl(baseUrl)
                        .client(okHttpClient.build())
                        .addConverterFactory(GsonConverterFactory.create())
                }
            }
        }
        return mBuilder!!
    }

    fun <T> createServiceAPI(clazz: Class<T>): T {
        return getRetrofitBuilder().build().create(clazz)
    }

    fun <T> createRequestService(clazz: Class<T>, mListener: IProgressListener): T {
        okHttpClient.addInterceptor(ProgressInterceptor(mListener))
        mListener.onStart()
        return getRetrofitBuilder().client(okHttpClient.build()).build().create(clazz)
    }

    fun <T> createService(clazz: Class<T>): T {
        return getRetrofitBuilder().client(okHttpClient.build()).build().create(clazz)
    }

    private val params: HashMap<String, RequestBody> = HashMap()

    fun clearParameter() {
        params.clear()
    }

    /**
     * 添加参数
     * 根据传进来的Object对象来判断是String还是File类型的参数
     */
    fun addParameter(key: String, o: Any): RetrofitClient {
        if (o is String) {
            val body: RequestBody = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), o)
            params[key] = body
        } else if (o is File) {
            val body: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), o)
            params[key + "\"; filename=\"" + o.name + ""] = body
        }
        return this
    }

    /**
     * 构建RequestBody
     */
    fun builder(): HashMap<String, RequestBody> {
        return params
    }

    /**
     * 更新平台地址
     *
     * @param httpUrl 平台地址
     */
    @Throws(Exception::class)
    fun updateBaseUrl(httpUrl: String) {
        if (httpUrl.length < 10) return
        try {
            baseUrl = httpUrl.takeIf { !it.endsWith(UploadConstant.SYMBOL_SLASH) }?.plus(UploadConstant.SYMBOL_SLASH)
                    ?: httpUrl
            mBuilder?.let {
                mBuilder = it.build().newBuilder().baseUrl(baseUrl)
            }
        } catch (ex: java.lang.Exception) {
            LogUtils.d("更新平台地址错误ex:[${ex.message}]")
        }
    }
}